<?php
    // +----------------------------------------------------------------------
    // | ThinkPHP [ WE CAN DO IT JUST THINK ]
    // +----------------------------------------------------------------------
    // | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved.
    // +----------------------------------------------------------------------
    // | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
    // +----------------------------------------------------------------------
    // | Author: liu21st <liu21st@gmail.com>
    // +----------------------------------------------------------------------
    namespace think\response;

    use think\Response;

    class Xml extends Response {
        // 输出参数
        protected $options     = [
            // 根节点名
            'root_node' => 'think',
            // 根节点属性
            'root_attr' => '',
            //数字索引的子节点名
            'item_node' => 'item',
            // 数字索引子节点key转换的属性名
            'item_key'  => 'id',
            // 数据编码
            'encoding'  => 'utf-8',
        ];
        protected $contentType = 'text/xml';

        /**
         * 处理数据
         * @access protected
         * @param mixed $data 要处理的数据
         * @return mixed
         */
        protected function output($data) {
            // XML数据转换
            return $this->xmlEncode($data, $this->options['root_node'], $this->options['item_node'], $this->options['root_attr'], $this->options['item_key'], $this->options['encoding']);
        }

        /**
         * XML编码
         * @param mixed  $data     数据
         * @param string $root     根节点名
         * @param string $item     数字索引的子节点名
         * @param string $attr     根节点属性
         * @param string $id       数字索引子节点key转换的属性名
         * @param string $encoding 数据编码
         * @return string
         */
        protected function xmlEncode($data, $root, $item, $attr, $id, $encoding) {
            if (is_array($attr)) {
                $array = [];
                foreach ($attr as $key => $value) {
                    $array[] = "{$key}=\"{$value}\"";
                }
                $attr = implode(' ', $array);
            }
            $attr = trim($attr);
            $attr = empty($attr) ? '' : " {$attr}";
            $xml  = "<?xml version=\"1.0\" encoding=\"{$encoding}\"?>";
            $xml  .= "<{$root}{$attr}>";
            $xml  .= $this->dataToXml($data, $item, $id);
            $xml  .= "</{$root}>";
            return $xml;
        }

        /**
         * 数据XML编码
         * @param mixed  $data 数据
         * @param string $item 数字索引时的节点名称
         * @param string $id   数字索引key转换为的属性名
         * @return string
         */
        protected function dataToXml($data, $item, $id) {
            $xml = $attr = '';
            foreach ($data as $key => $val) {
                if (is_numeric($key)) {
                    $id && $attr = " {$id}=\"{$key}\"";
                    $key = $item;
                }
                $xml .= "<{$key}{$attr}>";
                $xml .= (is_array($val) || is_object($val)) ? $this->dataToXml($val, $item, $id) : $val;
                $xml .= "</{$key}>";
            }
            return $xml;
        }
    }
